﻿using SharpDepend;
using SharpDepend.Datatypes;
using SoundEngine3.AudioFile;
using SoundEngine3.DspPlugins;
using System;
using System.Collections.Generic;
using System.IO;
using ZquenceStudio3.Core;
using ZquenceStudio3.DspPlugins;
using ZquenceStudio3.Core.Album;
using ZquenceStudio3Host.Graphics.Components;
using ZquenceStudio3Host.Graphics.GUI;
using ZquenceStudio3.Core.Utils;
using static ZquenceStudio3Host.DspPlugins.Synthesizers.SamplerSynth;
using ZquenceStudio3Host.Resources;

namespace ZquenceStudio3Host.DspPlugins.Synthesizers
{
    public class SamplerSynthUIDescription : IDspUIPlugin
    {
        public IDspUIPluginInfo GetDspUIPluginInfo()
        {
            return new DspUIPluginInfo<SamplerSynth, SamplerSynthUI>();
        }

        public BaseDspUIPluginAdapter CreateDspUI(ZquenceStudio3Context context, BaseDspPluginInstance dsp)
        {
            return new SamplerSynthUI();
        }
    }

    public class SamplerSynthUI : GuiDspPlugin, ISamplerSynthUI
    {
        private const int ITEM_HEIGHT = 30;
        
        private static Color s_itemColor = new Color(64, 66, 68, 80);
        private static int UniqueIdNext;
        
        private List<int> mReadyLabels = new List<int>();
        private SamplerSynth mSamplerSynth;
        private Panel mCurrentSelectedVisual;

        protected override void OnSetDspPlugin(BaseDspPluginInstance dsp)
        {
            mSamplerSynth = (SamplerSynth)dsp;
            mSamplerSynth.SetUI(this);
            mSamplerSynth.looping.DirectSet += delegate (double value)
            {
                if (m_loop != null)
                {
                    m_loop.IsActivated = mSamplerSynth.Loop;
                }
            };

            base.OnSetDspPlugin(dsp);
        }

        protected override void InitializeGuiComponents(Panel panel)
        {

            mCurrentSelectedVisual = new Panel(Gui, true);
            mCurrentSelectedVisual.DimensionInProcent = true;
            mCurrentSelectedVisual.X = 10;
            mCurrentSelectedVisual.Width = 80;
            mCurrentSelectedVisual.Height = 30;
            mCurrentSelectedVisual.Y = 65;
            mCurrentSelectedVisual.SetTexture("Images/Icons/musicmenu_stop.png");
            mCurrentSelectedVisual.BackgroundColor = Color.Orange;

            string UICode =
@"
[Panel]
{
	Name = FormDspAudioSamplerSynth;
	[Properties]
	{
		Text = Form window;
		Resize icon = NULL;
		Dimension procent = true;
		MinSize = 48 49;
		MaxSize = 2,147484E+09 2,147484E+09;
		Bg Color = 41 50 60 255;
		Overlay texture = NULL;
		Overlay texture color = 255 255 255 255;
		Name = FormDspAudioSamplerSynth;
		TagName = FormDspAudioSamplerSynth;
		Position = 0 0 0;
		Rotation = 0 0 0;
		Scale = 100 100 1;
		Visible = True;
	}
	[SpecificContents]
	{
	}
	[Components]
	{
		[Panel]
		{
			Name = Panel188;
			[Properties]
			{
				Dimension procent = True;
				MinSize = 0 0;
				MaxSize = 1E+10 1E+10;
				Bg Color = 153 153 153 255;
				Overlay texture = NULL;
				Overlay texture color = 255 255 255 255;
				Name = Panel188;
				TagName = ;
				Position = 0 0 0;
				Rotation = 0 0 0;
				Scale = 100 100 1;
				Visible = True;
			}
			[SpecificContents]
			{
			}
			[Components]
			{
				[Panel]
				{
					Name = Panel343;
					[Properties]
					{
						Dimension procent = True;
						MinSize = 0 0;
						MaxSize = 1E+10 1E+10;
						Bg Color = 153 153 153 255;
						Overlay texture = NULL;
						Overlay texture color = 255 255 255 255;
						Name = Panel343;
						TagName = Box;
						Position = -0,6835938 -0,3125 0;
						Rotation = 0 0 0;
						Scale = 101,7 101,5 0;
						Visible = True;
					}
					[SpecificContents]
					{
					}
				}
				[DialButton]
				{
					Name = DialButton189;
					[Properties]
					{
						Value = 49,83333;
						Max value = 100;
						Min value = 0;
						Multiplier = -1;
						Degrees Offset = 0;
						Degrees Max = 0;
						Center = True;
						Texture = NULL;
						Bg Color = 255 255 255 0;
						Lock to width = False;
						Lock to height = False;
						Dimension procent = True;
						MinSize = 0 0;
						MaxSize = 1E+10 1E+10;
						Bg Color = 255 255 255 0;
						Texture = NULL;
						Overlay texture = NULL;
						Overlay texture color = 255 255 255 255;
						Name = DialButton189;
						TagName = Pitch;
						Position = 76,25 50,15625 0;
						Rotation = 0 0 0;
						Scale = 22 27 1;
						Visible = True;
					}
					[SpecificContents]
					{
					}
				}
				[DialButton]
				{
					Name = DialButton190;
					[Properties]
					{
						Value = 51,00005;
						Max value = 100;
						Min value = 0;
						Multiplier = -1;
						Degrees Offset = 0;
						Degrees Max = 0;
						Center = False;
						Texture = NULL;
						Bg Color = 255 255 255 0;
						Lock to width = False;
						Lock to height = False;
						Dimension procent = True;
						MinSize = 0 0;
						MaxSize = 1E+10 1E+10;
						Bg Color = 255 255 255 0;
						Texture = NULL;
						Overlay texture = NULL;
						Overlay texture color = 255 255 255 255;
						Name = DialButton190;
						TagName = Volyme;
						Position = 76,25 21,875 0;
						Rotation = 0 0 0;
						Scale = 22 27 1;
						Visible = True;
					}
					[SpecificContents]
					{
					}
				}
				[Panel]
				{
					Name = Panel211;
					[Properties]
					{
						Dimension procent = True;
						MinSize = 0 0;
						MaxSize = 1E+10 1E+10;
						Bg Color = 151 138 159 255;
						Texture = NULL;
						Overlay texture = NULL;
						Overlay texture color = 255 255 255 255;
						Name = Panel211;
						TagName = PianoOctavesPanel;
						Position = 1,25 64,375 0;
						Rotation = 0 0 0;
						Scale = 75 34 0;
						Visible = True;
					}
					[SpecificContents]
					{
					}
				}
				[DialButton]
				{
					Name = DialButton212;
					[Properties]
					{
						Value = 49,83331;
						Max value = 100;
						Min value = 0;
						Multiplier = -1;
						Degrees Offset = 0;
						Degrees Max = 0;
						Center = True;
						Texture = NULL;
						Bg Color = 255 255 255 0;
						Lock to width = False;
						Lock to height = False;
						Dimension procent = True;
						MinSize = 0 0;
						MaxSize = 1E+10 1E+10;
						Bg Color = 255 255 255 0;
						Texture = NULL;
						Overlay texture = NULL;
						Overlay texture color = 255 255 255 255;
						Name = DialButton212;
						TagName = Note;
						Position = 76,25 77,5 0;
						Rotation = 0 0 0;
						Scale = 22 22 1;
						Visible = True;
					}
					[SpecificContents]
					{
					}
				}
				[Listbox2]
				{
					Name = Listbox2331;
					[Properties]
					{
						Expanded texture = NULL;
						Collapsed texture = NULL;
						Dimension procent = True;
						MinSize = 0 0;
						MaxSize = 1E+10 1E+10;
						Bg Color = 0 0 0 255;
						Overlay texture = NULL;
						Overlay texture color = 255 255 255 255;
						Name = Listbox2331;
						TagName = ListSamples;
						Position = 1,25 2,5 0;
						Rotation = 0 0 0;
						Scale = 75 60 0;
						Visible = True;
					}
					[SpecificContents]
					{
					}
				}
                [Button]
				{
					Name = Button339_;
					[Properties]
					{
						Bg Color = 255 255 255 255;
						Text = Auto set;
						Active = False;
						Bg color pressed = 120 150 210 255;
						Texture icon = ;
						Texture icon pressed = ;
						Texture icon size = 75;
						Color icon = 255 255 255 255;
						Color icon pressed = 255 255 255 255;
						Icon horizontal align = 0,5;
						Dimension procent = True;
						MinSize = 0 0;
						MaxSize = 1E+10 1E+10;
						Bg Color = 255 255 255 255;
						Overlay texture = NULL;
						Overlay texture color = 255 255 255 255;
						Name = Button339_;
						TagName = BtnAudoSet;
						Position = 77,5 2 0;
						Rotation = 0 0 0;
						Scale = 20 7,5 0;
						Visible = True;
					}
					[SpecificContents]
					{
					}
				}
				[Button]
				{
					Name = Button339;
					[Properties]
					{
						Bg Color = 255 255 255 255;
						Text = Loop;
						Active = True;
						Bg color pressed = 120 150 210 255;
						Texture icon = ;
						Texture icon pressed = ;
						Texture icon size = 75;
						Color icon = 255 255 255 255;
						Color icon pressed = 255 255 255 255;
						Icon horizontal align = 0,5;
						Dimension procent = True;
						MinSize = 0 0;
						MaxSize = 1E+10 1E+10;
						Bg Color = 255 255 255 255;
						Overlay texture = NULL;
						Overlay texture color = 255 255 255 255;
						Name = Button339;
						TagName = BtnLoop;
						Position = 77,5 10,625 0;
						Rotation = 0 0 0;
						Scale = 20 7,5 0;
						Visible = True;
					}
					[SpecificContents]
					{
					}
				}
				[Label]
				{
					Name = Label350;
					[Properties]
					{
						Text = Volyme;
						Text color = 255 255 255 255;
						Text size = 16;
						Text auto = True;
						Dimension procent = True;
						MinSize = 0 0;
						MaxSize = 1E+10 1E+10;
						Bg Color = 0 0 0 0;
						Texture = NULL;
						Overlay texture = NULL;
						Overlay texture color = 255 255 255 255;
						Name = Label350;
						TagName = ;
						Position = 77,5 18,75 0;
						Rotation = 0 0 0;
						Scale = 20 6 0;
						Visible = True;
					}
					[SpecificContents]
					{
					}
				}
				[Label]
				{
					Name = Label351;
					[Properties]
					{
						Text = Tune;
						Text color = 255 255 255 255;
						Text size = 16;
						Text auto = True;
						Dimension procent = True;
						MinSize = 0 0;
						MaxSize = 1E+10 1E+10;
						Bg Color = 0 0 0 0;
						Texture = NULL;
						Overlay texture = NULL;
						Overlay texture color = 255 255 255 255;
						Name = Label351;
						TagName = ;
						Position = 77,5 46,25 0;
						Rotation = 0 0 0;
						Scale = 20 6 0;
						Visible = True;
					}
					[SpecificContents]
					{
					}
				}
				[Label]
				{
					Name = Label352;
					[Properties]
					{
						Text = Note;
						Text color = 255 255 255 255;
						Text size = 16;
						Text auto = True;
						Dimension procent = True;
						MinSize = 0 0;
						MaxSize = 1E+10 1E+10;
						Bg Color = 0 0 0 0;
						Texture = NULL;
						Overlay texture = NULL;
						Overlay texture color = 255 255 255 255;
						Name = Label352;
						TagName = ;
						Position = 77,5 73,75 0;
						Rotation = 0 0 0;
						Scale = 20 6 0;
						Visible = True;
					}
					[SpecificContents]
					{
					}
				}
			}
		}
	}
}
";

            Gui.LoadUICode(UICode);

            Gui.MainPanel.BackgroundColor = Color.Transparent;

            foreach(var button in Gui.MainPanel.FindAll<Button>())
            {
                button.SetButtonColor(GlobalColors.ButtonColor);
            }

            // Get components.
            m_listOfSamples = (Listbox2)Gui.MainPanel.Find("TagName", "ListSamples");
            m_listOfSamples.OnSelectedListboxItem += new EventOnSelectedListbox2Item(m_listOfSamples_OnSelectedListboxItem);

            unchecked
            {
                m_listOfSamples.SetItemColorSelected(GlobalColors.BaseAudioColor);
            }

            DialButton m_volyme = (DialButton)Gui.MainPanel.Find("TagName", "Volyme");
            BindParameter(mSamplerSynth.volyme, m_volyme);

            DialButton m_pitch = (DialButton)Gui.MainPanel.Find("TagName", "Pitch");
            m_pitch.MinValue = -1;
            m_pitch.MaxValue = 1;
            BindParameter(mSamplerSynth.pitch, m_pitch);

            DialButton  m_note = (DialButton)Gui.MainPanel.Find("TagName", "Note");
            m_note.MinValue = -12;
            m_note.MaxValue = 12;
            m_note.AsInteger = true;
            BindParameter(mSamplerSynth.note, m_note);

            Button m_autoSet = (Button)Gui.MainPanel.Find("TagName", "BtnAudoSet");
            m_autoSet.OnClicked += M_autoSet_OnClicked;

            m_loop = (Button)Gui.MainPanel.Find("TagName", "BtnLoop");
            m_loop.OnActivate += m_loop_OnActivate;
            m_loop.OnDeactivate += m_loop_OnDeactivate;
            m_loop.IsActivated = mSamplerSynth.Loop;

            m_panel = (Panel)Gui.MainPanel.Find("TagName", "PianoOctavesPanel");

            m_piano = new PianoPanel(base.Gui, true);
            m_piano.BackgroundColor = Color.Black;
            m_piano.OnNotePressed += m_piano_OnNotePressed;
            m_piano.OnNoteReleased += m_piano_OnNoteReleased;
            m_piano.DimensionInProcent = true;
            m_piano.Width = 100;
            m_piano.Height = 100;
            m_panel.AddComponent(m_piano);

            InitializeListbox();

            // Initialize labels if the has been set before GUI initialization.
            if (mReadyLabels.Count > 0)
            {
                foreach (var note in mReadyLabels)
                {
                    InsertLabelInNote(note);
                }
                mReadyLabels.Clear();
            }
        }
        
        private FileItem mLastFolderPath = null;

        private void FolderItem_OnSelectedListboxItem(object sender, Listbox2Item selectedItem)
        {
            mLastFolderPath = (FileItem)selectedItem.ItemObject;

            if (mLastFolderPath == null)
            {
                selectedItem.Unselect();

                mSamplerSynth.UnloadAudio(m_lastSelectedNote);
            }
        }

        private void M_autoSet_OnClicked(object sender, double x, double y, int id)
        {
            if (mLastFolderPath != null)
            {
                AudioSetPath(mLastFolderPath);
            }
        }

        private void AudioSetPath(FileItem folderPath)
        {
            // Warning the user that all settings will be lost.
            SharpDepend.Manager.DialogManager.Show(
                "Auto set will clear settings. Do you want to continue?",
                "Auto set",
                SharpDepend.DialogButtons.YesNo,
                SharpDepend.DialogIcon.Warning,
                AutoSetPathResult, folderPath);
        }

        void AutoSetPathResult(DialogButtonResult clickedButton, object parameter)
        {
            FileItem folderPath = (FileItem)parameter;

            if (SharpDepend.Manager.FileManager.PathExist(folderPath.Path, true))
            {
                // Remove all samples.
                mSamplerSynth.ClearAudioSamples();

                var files = folderPath.Children;

                int i = -1;

                foreach (var file in files)
                {
                    if (file.IsFile)
                    {
                        string filename = StringUtils.GetFilenameFromFullPath(file.Path).ToLower();

                        switch (filename)
                        {
                            case "c0": LoadAudioFromFile(file, 12 * 0); break;
                            case "c1": LoadAudioFromFile(file, 12 * 1); break;
                            case "c2": LoadAudioFromFile(file, 12 * 2); break;
                            case "c3": LoadAudioFromFile(file, 12 * 3); break;
                            case "c4": LoadAudioFromFile(file, 12 * 4); break;
                            case "c5": LoadAudioFromFile(file, 12 * 5); break;
                            case "c6": LoadAudioFromFile(file, 12 * 6); break;
                            case "c7": LoadAudioFromFile(file, 12 * 7); break;
                            case "c8": LoadAudioFromFile(file, 12 * 8); break;
                            case "c9": LoadAudioFromFile(file, 12 * 9); break;
                            case "c10": LoadAudioFromFile(file, 12 * 10); break;
                            case "c11": LoadAudioFromFile(file, 12 * 11); break;
                            default:
                                LoadAudioFromFile(file, ++i);
                                break;
                        }
                    }
                }

                if (folderPath.Path.Contains("looped"))
                {
                    m_loop.IsActivated = true;
                }
            }
        }
        
        /// <summary>
        /// Calls when user clicks on a audio item from the listbox.
        /// </summary>
        private void m_listOfSamples_OnSelectedListboxItem(object sender, Listbox2Item selectedItem)
        {
            // Get file.
            FileItem file = (FileItem)selectedItem.ItemObject;

            if (file != null)
            {
                // If no note is selected. Then just take the first note.
                if (m_lastSelectedNote == -1)
                {
                    m_lastSelectedNote = 0;
                }

                mSamplerSynth.UnloadAudio(m_lastSelectedNote);
                LoadAudioFromFile(file, m_lastSelectedNote);

                // Preview play.
                Application.PreviewFileItem(file);
            }
        }

        //------------------------------------------------------------------------------------------------------------------------
        void m_loop_OnActivate(object sender, double x, double y, int id)
        {
            // Set infinity loops
            mSamplerSynth.looping.RawValue = 1;
        }

        //------------------------------------------------------------------------------------------------------------------------
        void m_loop_OnDeactivate(object sender, double x, double y, int id)
        {
            // Set one loop.
            mSamplerSynth.looping.RawValue = 0;
        }

        private Listbox2 m_listOfSamples;
        private int m_lastSelectedNote = -1;
        private List<int> m_mappedNotes = new List<int>();
        private DialButton m_volyme;
        private DialButton m_pitch;
        private DialButton m_note;
        private Button m_loop;
        private Panel m_panel;
        private PianoPanel m_piano;
        private Dictionary<int, Panel> m_mappedLabel = new Dictionary<int, Panel>();
        
        //------------------------------------------------------------------------------------------------------------------------
        void m_piano_OnNotePressed(int note, int velocity)
        {
            BaseDsp.PressNote((byte)note, (byte)velocity, 0.0);
        }

        //------------------------------------------------------------------------------------------------------------------------
        void m_piano_OnNoteReleased(int note)
        {
            if (m_piano.IsPanelAddedNote(mCurrentSelectedVisual, m_lastSelectedNote))
            {
                m_piano.RemovePanelFromNote(mCurrentSelectedVisual, m_lastSelectedNote);
            }

            m_lastSelectedNote = note;
            
            m_piano.AddComponentToNote(mCurrentSelectedVisual, note);

            BaseDsp.ReleaseNote((byte)note, 0, 0.0);
        }

        private Listbox2Item mNoneItem;

        /// <summary>
        /// Load folders and files.
        /// </summary>
        private void InitializeListbox()
        {
            mNoneItem = new Listbox2Item(Gui, "None", null);
            mNoneItem.OnSelectedListboxItem += FolderItem_OnSelectedListboxItem;
            m_listOfSamples.AddItem(mNoneItem);

            foreach (FileItem path in Application.Library.Paths)
            {
                // Add folder item.
                Listbox2Item folderItem = new Listbox2Item(Gui, path.Filename, path);
                folderItem.SetExpandedTexture(Gui.FileManager.LoadTexture2("Images/Icons/albumexp_folder.png"));
                folderItem.SetCollapsedTexture(Gui.FileManager.LoadTexture2("Images/Icons/albumexp_folder.png"));
                folderItem.SetItemColor(s_itemColor);
                folderItem.SetItemColorSelected(m_listOfSamples.GetItemColorSelected());
                folderItem.Height = ITEM_HEIGHT;

                // Add click event on folder.
                folderItem.OnSelectedListboxItem += FolderItem_OnSelectedListboxItem;

                m_listOfSamples.AddItem(folderItem);

                FixItem(folderItem, path, 1);

                folderItem.Collapse();
            }
            
            m_listOfSamples.Expand();
        }

        /// <summary>
        /// Calls from UI.
        /// </summary>
        /// <param name="file"></param>
        /// <param name="note"></param>
        private void LoadAudioFromFile(FileItem file, int note)
        {
            // Check if file item already exist in album. Then clone it and rename it with a unique name.
            ContentFile contentFromAlbum = Application.GetContentFileByFileItem(file);

            // If file exist in album.
            if (contentFromAlbum != null)
            {
                // If the content is not included in this synth, then make content duplicated.
                string filenameWithExtension = StringUtils.GetFilenameOrFolderNameFromFullPath(file.Path);
                ContentFile content = mSamplerSynth.GetContentFileByFilename(filenameWithExtension);

                // Content did not exist in this synth, it may exist in another synth so clone this content.
                // But check the checksum of the files and compare, If difference, make filename unique and clone it.
                bool fileEqual = FileHelper.FileEqual(file.Path, contentFromAlbum.FromAlbumFilePath);
                if (content == null && !fileEqual)
                {
                    // Clone.
                    Stream stream;
                    ContentFile newContent = mSamplerSynth.CoreContext.CreateUniqueContentFile(contentFromAlbum.FilenameWithExtension, out stream);
                    using (stream)
                    {
                        using (Stream copyFrom = SharpDepend.Manager.FileManager.OpenFile(file.Path))
                        {
                            copyFrom.CopyTo(stream);
                        }
                    }
                    
                    LoadAudioFromFile(newContent.FromAlbumFilePath, note, null);
                }
                else if(content != null && !fileEqual)
                {
                    // Clone.
                    Stream stream;
                    ContentFile newContent = mSamplerSynth.CoreContext.CreateUniqueContentFile(contentFromAlbum.FilenameWithExtension, out stream);
                    using (stream)
                    {
                        using (Stream copyFrom = SharpDepend.Manager.FileManager.OpenFile(file.Path))
                        {
                            copyFrom.CopyTo(stream);
                        }
                    }

                    LoadAudioFromFile(newContent.FromAlbumFilePath, note, null);
                }
                else
                {
                    // Just take the same content file, it already exist in same synth and file was equal or
                    // content was in album and has equal files.
                    LoadAudioFromFile(file.Path, note, null);
                }
            }
            else
            {
                LoadAudioFromFile(file.Path, note, null);
            }
        }
        
        /// <summary>
        /// Calls from internal.
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="note"></param>
        /// <param name="customStream"></param>
        private void LoadAudioFromFile(string filePath, int note, Stream customStream)
        {
            // Add file to album and attach to this dsp.
            ContentFile content = mSamplerSynth.GetContentFileByFilename(filePath);
            if (content == null)
            {
                string filenameWithExtension = StringUtils.GetFilenameOrFolderNameFromFullPath(filePath);

                // Check if the content file already exist in album.
                content = mSamplerSynth.CoreContext.GetContentFileByFileItem(filenameWithExtension);

                if (content == null)
                {
                    // Add to album.
                    content = mSamplerSynth.CoreContext.CopyFileItemToAlbum(filePath);
                    // Make this content file removable when not used.
                    content.AllowAutomaticRemoveWhenNotUsed = true;

                }
                else
                {
                    bool fileEqual = FileHelper.FileEqual(filePath, content.FromAlbumFilePath);

                    if (!fileEqual)
                    {
                        // Add to album.
                        content = mSamplerSynth.CoreContext.CopyFileItemToAlbum(filePath);

                        // Make this content file removable when not used.
                        content.AllowAutomaticRemoveWhenNotUsed = true;
                    }
                }

                mSamplerSynth.AddContentFile(content);
            }

            _LoadAudioFromContent(note, customStream, content);
        }

        public bool LoopIsActivated
        {
            get
            {
                return m_loop.IsActivated;
            }
            set
            {
                m_loop.IsActivated = value;
            }
        }

        private void _LoadAudioFromContent(int note, Stream customStream, ContentFile content)
        {
            // Create audio from file.
            AudioBase audioFile = null;

            if (customStream == null)
            {
                // Check if file exist. Otherwise audioFile will be null and no audio will be loaded.
                //if (Application.Core.FileSystem.PathExist(content.FromAlbumFilePath, false))
                if(mSamplerSynth.CoreContext.ContentFileExistOnDisk(content))
                {
                    //using (var stream = Application.Core.FileSystem.OpenFile(content.FromAlbumFilePath))
                    using (var stream = mSamplerSynth.CoreContext.OpenContentFile(content))
                    {
                        audioFile = BaseDsp.SoundEngineContext.CreateAudioSampleByStream(stream);
                    }
                }
                else
                {
                    // Display what file that was missing when synthesizer has been loaded.
                    mSamplerSynth.AddError("'" + content.FromAlbumFilePath + "' was not found on disk.");
                }
            }
            else
            {
                audioFile = BaseDsp.SoundEngineContext.CreateAudioSampleByStream(customStream);
            }

            // Load audio only if file exist or available.
            if (audioFile != null)
            {
                // Add a char on note if an audio is mapped.
                if (!mSamplerSynth.AudioExist(note))
                {
                    InsertLabelInNote(note);
                }

                // Try to get cached audio.
                AudioBaseWithPath audio = mSamplerSynth.GetAudioBase(content.FilenameWithExtension);

                // If not yet cached, create one.
                if (audio == null)
                {
                    audio = new AudioBaseWithPath { Audio = audioFile, File = content };
                }

                // Insert audio to the audio sampler synth.
                mSamplerSynth.LoadAudio(audio, note);
            }
        }

        public void RemoveLabelInNote(int note)
        {
            if (m_mappedLabel.ContainsKey(note))
            {
                Panel panel = m_mappedLabel[note];
                m_mappedLabel.Remove(note);
                m_piano.RemovePanelFromNote(panel, note);
                m_piano.SetNoteColor(Color.White, note);
            }
        }

        public void InsertLabelInNote(int note)
        {
            if (m_piano == null)
            {
                mReadyLabels.Add(note);
            }
            else
            {
                Panel lbl = new Panel(Gui, true);
                lbl.DimensionInProcent = true;
                lbl.Width = 100;
                lbl.Height = 40;
                lbl.Y = 60;
                lbl.SetTexture("Images/Icons/musicmenu_stop.png");
                lbl.BackgroundColor = Color.Blue;
                m_piano.AddComponentToNote(lbl, note);
                m_piano.SetNoteColor(Color.LightBlue, note);

                m_mappedLabel.Add(note, lbl);

                m_mappedNotes.Add(note);
            }
        }

        private void FixItem(Listbox2Item inItem, FileItem folder, int deep)
        {
            if (folder.IsFile)
            {
                throw new Exception("folder parameter is a File. Only Folder is allowed.");
            }

            ++deep;

            //string[] folders = SharpDepend.Manager.FileManager.ListFolders(folder);
            IEnumerable<FileItem> children = folder.Children;

            foreach (var child in children)
            {
                if (child.IsFolder)
                {
                    string subFolder = child.Path;

                    // Fix the '/blabla' to 'blabla' problem.
                    string folderName = StringUtils.GetFilenameOrFolderNameFromFullPath(subFolder);

                    // Add folder item.
                    Listbox2Item folderItem = new Listbox2Item(Gui, folderName, child);
                    folderItem.Height = ITEM_HEIGHT;
                    folderItem.SetExpandedTexture(Gui.FileManager.LoadTexture2("Images/Icons/albumexp_folder.png"));
                    folderItem.SetCollapsedTexture(Gui.FileManager.LoadTexture2("Images/Icons/albumexp_folder.png"));
                    folderItem.SetItemColor(s_itemColor);

                    // Add click event on folder.
                    folderItem.OnSelectedListboxItem += FolderItem_OnSelectedListboxItem;

                    inItem.AddItem(folderItem);

                    FixItem(folderItem, child, deep);

                    folderItem.Collapse();
                }
                else
                {
                    // Get AFile.
                    string file = child.Path;

                    // Check if file path is supported.
                    if (BaseDsp.SoundEngineContext.FileTypeSupported(file))
                    {
                        // Create listbox item.
                        string filePath = StringUtils.GetFilenameOrFolderNameFromFullPath(file);
                        Listbox2Item item = new Listbox2Item(Gui, filePath, child);
                        item.SetExpandedTexture(Gui.FileManager.LoadTexture2("Images/Icons/albumexp_sample.png"));
                        item.SetCollapsedTexture(Gui.FileManager.LoadTexture2("Images/Icons/albumexp_sample.png"));
                        item.SetItemColor(Color.Transparent);
                        item.Height = ITEM_HEIGHT;

                        // Add click event on file.
                        item.OnSelectedListboxItem += m_listOfSamples_OnSelectedListboxItem;

                        // Add item.
                        inItem.AddItem(item);

                        item.Collapse();
                    }
                }
            }
        }
    }
}
